package com.jame.singleton;

/**
 * @author : Jame
 * @date : 2022-04-15 11:24
 * 单例模式-懒汉
 **/
public class SingletonLazy {
    /**
     * 创建静态变量用来存放对象的实例
     */
    private  /* volatile */  static SingletonLazy singletonLazy;



    /**
     * 私有构造方法
     */
    private SingletonLazy() {

    }

    /**
     * 在多线程情况下可能会两个线程都进入判断
     * 例如线程1走进if后准备创建对象,然后时间片用完切换到线程2
     * 线程2进入发现singleton为空,然后创建对象
     * 之后线程1得到时间片继续执行new对象的操作,这时候就存在了多个实例
     *
     * @return
     */
    public static SingletonLazy getSingletonLazy() {
        if (singletonLazy == null) {
            singletonLazy = new SingletonLazy();
        }
        return singletonLazy;
    }


    /**
     * 使用synchronized可以解决多实例问题
     * 但是如果这个方法经常被访问每次都加锁影响性能
     *
     * @return
     */
    public synchronized static SingletonLazy getSynchronizedSingletonLazy() {
        if (singletonLazy == null) {
            singletonLazy = new SingletonLazy();
        }
        return singletonLazy;
    }


    /**
     * 使用double-check加volatile来解决每次都加锁的问题
     *
     * @return
     */
    public static SingletonLazy getSynchronizedDoubleCheckSingletonLazy() {
        if (singletonLazy == null) {
            synchronized (SingletonLazy.class) {
                if (singletonLazy == null) {
                    singletonLazy = new SingletonLazy();
                }
            }
        }
        return singletonLazy;
    }

}
